home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / steal.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  8KB  |  349 lines

  1. /*    SCCS Id: @(#)steal.c    3.1    92/10/14    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. STATIC_DCL int NDECL(stealarm);
  8.  
  9. #ifdef OVLB
  10. static const char * FDECL(equipname, (struct obj *));
  11.  
  12. static const char *
  13. equipname(otmp)
  14.  
  15.     register struct obj *otmp;
  16. {
  17.  
  18.     return (
  19. #ifdef TOURIST
  20.         (otmp == uarmu) ? "shirt" :
  21. #endif
  22.         (otmp == uarmf) ? "boots" :
  23.         (otmp == uarms) ? "shield" :
  24.         (otmp == uarmg) ? "gloves" :
  25.         (otmp == uarmc) ? "cloak" :
  26.         (otmp == uarmh) ? "helmet" : "armor");
  27. }
  28.  
  29. long        /* actually returns something that fits in an int */
  30. somegold(){
  31. #ifdef LINT    /* long conv. ok */
  32.     return(0L);
  33. #else
  34.     return (long)( (u.ugold < 100) ? u.ugold :
  35.         (u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) );
  36. #endif
  37. }
  38.  
  39. void
  40. stealgold(mtmp)
  41. register struct monst *mtmp;
  42. {
  43.     register struct obj *gold = g_at(u.ux, u.uy);
  44.     register long tmp;
  45.  
  46.     if (gold && ( !u.ugold || gold->quan > u.ugold || !rn2(5))) {
  47.         mtmp->mgold += gold->quan;
  48.         delobj(gold);
  49.         newsym(u.ux, u.uy);
  50.         pline("%s quickly snatches some gold from between your %s!",
  51.             Monnam(mtmp), makeplural(body_part(FOOT)));
  52.         if(!u.ugold || !rn2(5)) {
  53.         rloc(mtmp);
  54.         mtmp->mflee = 1;
  55.         }
  56.     } else if(u.ugold) {
  57.         u.ugold -= (tmp = somegold());
  58.         Your("purse feels lighter.");
  59.         mtmp->mgold += tmp;
  60.         rloc(mtmp);
  61.         mtmp->mflee = 1;
  62.         flags.botl = 1;
  63.     }
  64. }
  65.  
  66. /* steal armor after you finish taking it off */
  67. unsigned int stealoid;        /* object to be stolen */
  68. unsigned int stealmid;        /* monster doing the stealing */
  69.  
  70. STATIC_OVL int
  71. stealarm(){
  72.     register struct monst *mtmp;
  73.     register struct obj *otmp;
  74.  
  75.     for(otmp = invent; otmp; otmp = otmp->nobj)
  76.       if(otmp->o_id == stealoid) {
  77.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  78.           if(mtmp->m_id == stealmid) {
  79.           if(otmp->unpaid) 
  80.                subfrombill(otmp, shop_keeper(*u.ushops));
  81.           freeinv(otmp);
  82.           pline("%s steals %s!", Monnam(mtmp), doname(otmp));
  83.           mpickobj(mtmp,otmp);
  84.           mtmp->mflee = 1;
  85.           rloc(mtmp);
  86.         break;
  87.           }
  88.         break;
  89.       }
  90.     stealoid = 0;
  91.     return 0;
  92. }
  93.  
  94. /* Returns 1 when something was stolen (or at least, when N should flee now)
  95.  * Returns -1 if the monster died in the attempt
  96.  * Avoid stealing the object stealoid
  97.  */
  98. int
  99. steal(mtmp)
  100. struct monst *mtmp;
  101. {
  102.     register struct obj *otmp;
  103.     register int tmp;
  104.     register int named = 0;
  105.  
  106.     /* the following is true if successful on first of two attacks. */
  107.     if(!monnear(mtmp, u.ux, u.uy)) return(0);
  108.  
  109.     if(!invent
  110. #ifdef POLYSELF
  111.            || (inv_cnt() == 1 && uskin)
  112. #endif
  113.                         ){
  114.         /* Not even a thousand men in armor can strip a naked man. */
  115.         if(Blind)
  116.           pline("Somebody tries to rob you, but finds nothing to steal.");
  117.         else
  118.           pline("%s tries to rob you, but she finds nothing to steal!",
  119.         Monnam(mtmp));
  120.         return(1);    /* let her flee */
  121.     }
  122.  
  123.     if(Adornment & LEFT_RING) {
  124.         otmp = uleft;
  125.         goto gotobj;
  126.     } else if(Adornment & RIGHT_RING) {
  127.         otmp = uright;
  128.         goto gotobj;
  129.     }
  130.  
  131.     tmp = 0;
  132.     for(otmp = invent; otmp; otmp = otmp->nobj)
  133.         if((!uarm || otmp != uarmc)
  134. #ifdef POLYSELF
  135.                     && otmp != uskin
  136. #endif
  137.                             )
  138.         tmp += ((otmp->owornmask &
  139.             (W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1);
  140.     tmp = rn2(tmp);
  141.     for(otmp = invent; otmp; otmp = otmp->nobj)
  142.         if((!uarm || otmp != uarmc)
  143. #ifdef POLYSELF
  144.                     && otmp != uskin
  145. #endif
  146.                             )
  147.         if((tmp -= ((otmp->owornmask &
  148.             (W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1)) < 0)
  149.             break;
  150.     if(!otmp) {
  151.         impossible("Steal fails!");
  152.         return(0);
  153.     }
  154.     /* can't steal gloves while wielding - so steal the wielded item. */
  155.     if (otmp == uarmg && uwep)
  156.         otmp = uwep;
  157.     /* can't steal armor while wearing cloak - so steal the cloak. */
  158.     else if(otmp == uarm && uarmc) otmp = uarmc;
  159. #ifdef TOURIST
  160.     else if(otmp == uarmu && uarmc) otmp = uarmc;
  161.     else if(otmp == uarmu && uarm) otmp = uarm;
  162. #endif
  163. gotobj:
  164.     if(otmp->o_id == stealoid) return(0);
  165.  
  166. #ifdef WALKIES
  167.     if(otmp->otyp == LEASH && otmp->leashmon) o_unleash(otmp);
  168. #endif
  169.  
  170.     if((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))){
  171.         switch(otmp->oclass) {
  172.         case TOOL_CLASS:
  173.             Blindf_off(otmp);
  174.             break;
  175.         case AMULET_CLASS:
  176.             Amulet_off();
  177.             break;
  178.         case RING_CLASS:
  179.             Ring_gone(otmp);
  180.             break;
  181.         case ARMOR_CLASS:
  182.             /* Stop putting on armor which has been stolen. */
  183.             if (donning(otmp)) {
  184.               cancel_don();
  185.               if (otmp == uarm)  (void) Armor_off();
  186.               /* else if (otmp == uarmc) (void) Cloak_off(); */
  187.               else if (otmp == uarmf) (void) Boots_off();
  188.               else if (otmp == uarmg) (void) Gloves_off();
  189.               else if (otmp == uarmh) (void) Helmet_off();
  190.               /* else if (otmp == uarms) (void) Shield_off(); */
  191.               else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
  192.               break;
  193.             }
  194.             { int curssv = otmp->cursed;
  195.             otmp->cursed = 0;
  196.             stop_occupation();
  197.             if(flags.female)
  198.                 pline("%s charms you.  You gladly %s your %s.",
  199.                   Blind ? "She" : Monnam(mtmp),
  200.                   curssv ? "let her take" : "hand over",
  201.                   equipname(otmp));
  202.             else
  203.                 pline("%s seduces you and %s off your %s.",
  204.                   Blind ? "It" : Adjmonnam(mtmp, "beautiful"),
  205.                   curssv ? "helps you to take" : "you start taking",
  206.                   equipname(otmp));
  207.             named++;
  208.             /* the following is to set multi for later on */
  209.             nomul(-objects[otmp->otyp].oc_delay);
  210.  
  211.             if (otmp == uarm)  (void) Armor_off();
  212.             else if (otmp == uarmc) (void) Cloak_off();
  213.             else if (otmp == uarmf) (void) Boots_off();
  214.             else if (otmp == uarmg) (void) Gloves_off();
  215.             else if (otmp == uarmh) (void) Helmet_off();
  216.             else if (otmp == uarms) (void) Shield_off();
  217.             else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
  218.             otmp->cursed = curssv;
  219.             if(multi < 0){
  220.                 /*
  221.                 multi = 0;
  222.                 nomovemsg = 0;
  223.                 afternmv = 0;
  224.                 */
  225.                 stealoid = otmp->o_id;
  226.                 stealmid = mtmp->m_id;
  227.                 afternmv = stealarm;
  228.                 return(0);
  229.             }
  230.             break;
  231.             }
  232.         default:
  233.             impossible("Tried to steal a strange worn thing.");
  234.         }
  235.     }
  236.     else if(otmp == uwep) uwepgone();
  237.  
  238.     if(otmp == uball) unpunish();
  239.  
  240.     freeinv(otmp);
  241.     pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
  242.     (void) snuff_candle(otmp);
  243.     mpickobj(mtmp,otmp);
  244.     if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
  245.         && !resists_ston(mtmp->data)) {
  246.         pline("%s turns to stone.", Monnam(mtmp));
  247.         stoned = TRUE;
  248.         xkilled(mtmp, 0);
  249.         return -1;
  250.     }
  251.     return((multi < 0) ? 0 : 1);
  252. }
  253.  
  254. #endif /* OVLB */
  255. #ifdef OVL1
  256.  
  257. void
  258. mpickobj(mtmp,otmp)
  259. register struct monst *mtmp;
  260. register struct obj *otmp;
  261. {
  262.     otmp->nobj = mtmp->minvent;
  263.     mtmp->minvent = otmp;
  264. }
  265.  
  266. #endif /* OVL1 */
  267. #ifdef OVLB
  268.  
  269. void
  270. stealamulet(mtmp)
  271. register struct monst *mtmp;
  272. {
  273.     register struct obj *otmp;
  274.  
  275.     for(otmp = invent; otmp; otmp = otmp->nobj) {
  276.         if(otmp->otyp == AMULET_OF_YENDOR ||
  277.            (otmp->otyp == FAKE_AMULET_OF_YENDOR && !mtmp->iswiz)) {
  278.         /* might be an imitation one */
  279.         setnotworn(otmp);
  280.         freeinv(otmp);
  281.         mpickobj(mtmp,otmp);
  282.         pline("%s stole %s!", Monnam(mtmp), doname(otmp));
  283.         if (can_teleport(mtmp->data)) rloc(mtmp);
  284.         return;
  285.         }
  286.     }
  287. }
  288.  
  289. #endif /* OVLB */
  290. #ifdef OVL0
  291.  
  292. /* release the objects the killed animal was carrying */
  293. void
  294. relobj(mtmp,show,is_pet)
  295. register struct monst *mtmp;
  296. register int show;
  297. boolean is_pet;        /* If true, pet should keep wielded weapon */
  298. {
  299.     register struct obj *otmp, *otmp2;
  300.     register int omx = mtmp->mx, omy = mtmp->my;
  301.  
  302. #ifdef MUSE
  303.     otmp2 = otmp = 0;
  304.     if (is_pet) {
  305.         sort_mwep(mtmp);
  306.         if ((otmp2 = MON_WEP(mtmp))) {
  307.             otmp = otmp2->nobj;
  308.             otmp2->nobj = 0;
  309.         }
  310.     }
  311.     if (!otmp2)
  312. #endif
  313.     {    otmp = mtmp->minvent;
  314.         mtmp->minvent = 0;
  315.     }
  316.  
  317.     for (; otmp; otmp = otmp2) {
  318. #ifdef MUSE
  319.         if (otmp->owornmask) {
  320.             mtmp->misc_worn_check &= ~(otmp->owornmask);
  321.             otmp->owornmask = 0L;
  322.         }
  323. #endif
  324.         otmp2 = otmp->nobj;
  325.         if (is_pet && cansee(omx, omy) && flags.verbose)
  326.             pline("%s drops %s.", Monnam(mtmp),
  327.                     distant_name(otmp, doname));
  328.         if (flooreffects(otmp, omx, omy, "fall")) continue;
  329.         place_object(otmp, omx, omy);
  330.         otmp->nobj = fobj;
  331.         fobj = otmp;
  332.         stackobj(fobj);
  333.     }
  334.     if (mtmp->mgold) {
  335.         register long g = mtmp->mgold;
  336.         mkgold(g, omx, omy);
  337.         if (is_pet && cansee(omx, omy) && flags.verbose)
  338.             pline("%s drops %ld gold piece%s.", Monnam(mtmp),
  339.                 g, plur(g));
  340.         mtmp->mgold = 0L;
  341.     }
  342.     if (show & cansee(omx, omy))
  343.         newsym(omx, omy);
  344. }
  345.  
  346. #endif /* OVL0 */
  347.  
  348. /*steal.c*/
  349.